1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gsk.Transform;
26 
27 private import glib.ConstructionException;
28 private import glib.MemorySlice;
29 private import glib.Str;
30 private import glib.StringG;
31 private import glib.c.functions;
32 private import gobject.ObjectG;
33 private import graphene.Matrix;
34 private import graphene.Point;
35 private import graphene.Point3D;
36 private import graphene.Rect;
37 private import graphene.Vec3;
38 private import gsk.c.functions;
39 public  import gsk.c.types;
40 private import linker.Loader;
41 
42 
43 /**
44  * `GskTransform` is an object to describe transform matrices.
45  * 
46  * Unlike `graphene_matrix_t`, `GskTransform` retains the steps in how
47  * a transform was constructed, and allows inspecting them. It is modeled
48  * after the way CSS describes transforms.
49  * 
50  * `GskTransform` objects are immutable and cannot be changed after creation.
51  * This means code can safely expose them as properties of objects without
52  * having to worry about others changing them.
53  */
54 public class Transform
55 {
56 	/** the main Gtk struct */
57 	protected GskTransform* gskTransform;
58 	protected bool ownedRef;
59 
60 	/** Get the main Gtk struct */
61 	public GskTransform* getTransformStruct(bool transferOwnership = false)
62 	{
63 		if (transferOwnership)
64 			ownedRef = false;
65 		return gskTransform;
66 	}
67 
68 	/** the main Gtk struct as a void* */
69 	protected void* getStruct()
70 	{
71 		return cast(void*)gskTransform;
72 	}
73 
74 	/**
75 	 * Sets our main struct and passes it to the parent class.
76 	 */
77 	public this (GskTransform* gskTransform, bool ownedRef = false)
78 	{
79 		this.gskTransform = gskTransform;
80 		this.ownedRef = ownedRef;
81 	}
82 
83 	~this ()
84 	{
85 		if ( Linker.isLoaded(LIBRARY_GSK[0]) && ownedRef )
86 			gsk_transform_unref(gskTransform);
87 	}
88 
89 
90 	/** */
91 	public static GType getType()
92 	{
93 		return gsk_transform_get_type();
94 	}
95 
96 	/** */
97 	public this()
98 	{
99 		auto __p = gsk_transform_new();
100 
101 		if(__p is null)
102 		{
103 			throw new ConstructionException("null returned by new");
104 		}
105 
106 		this(cast(GskTransform*) __p);
107 	}
108 
109 	/**
110 	 * Checks two transforms for equality.
111 	 *
112 	 * Params:
113 	 *     second = the second transform
114 	 *
115 	 * Returns: %TRUE if the two transforms perform the same operation
116 	 */
117 	public bool equal(Transform second)
118 	{
119 		return gsk_transform_equal(gskTransform, (second is null) ? null : second.getTransformStruct()) != 0;
120 	}
121 
122 	/**
123 	 * Returns the category this transform belongs to.
124 	 *
125 	 * Returns: The category of the transform
126 	 */
127 	public GskTransformCategory getCategory()
128 	{
129 		return gsk_transform_get_category(gskTransform);
130 	}
131 
132 	/**
133 	 * Inverts the given transform.
134 	 *
135 	 * If @self is not invertible, %NULL is returned.
136 	 * Note that inverting %NULL also returns %NULL, which is
137 	 * the correct inverse of %NULL. If you need to differentiate
138 	 * between those cases, you should check @self is not %NULL
139 	 * before calling this function.
140 	 *
141 	 * Returns: The inverted transform
142 	 */
143 	public Transform invert()
144 	{
145 		auto __p = gsk_transform_invert(gskTransform);
146 
147 		if(__p is null)
148 		{
149 			return null;
150 		}
151 
152 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
153 	}
154 
155 	/**
156 	 * Multiplies @next with the given @matrix.
157 	 *
158 	 * Params:
159 	 *     matrix = the matrix to multiply @next with
160 	 *
161 	 * Returns: The new transform
162 	 */
163 	public Transform matrix(Matrix matrix)
164 	{
165 		auto __p = gsk_transform_matrix(gskTransform, (matrix is null) ? null : matrix.getMatrixStruct());
166 
167 		if(__p is null)
168 		{
169 			return null;
170 		}
171 
172 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
173 	}
174 
175 	/**
176 	 * Applies a perspective projection transform.
177 	 *
178 	 * This transform scales points in X and Y based on their Z value,
179 	 * scaling points with positive Z values away from the origin, and
180 	 * those with negative Z values towards the origin. Points
181 	 * on the z=0 plane are unchanged.
182 	 *
183 	 * Params:
184 	 *     depth = distance of the z=0 plane. Lower values give a more
185 	 *         flattened pyramid and therefore a more pronounced
186 	 *         perspective effect.
187 	 *
188 	 * Returns: The new transform
189 	 */
190 	public Transform perspective(float depth)
191 	{
192 		auto __p = gsk_transform_perspective(gskTransform, depth);
193 
194 		if(__p is null)
195 		{
196 			return null;
197 		}
198 
199 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
200 	}
201 
202 	/**
203 	 * Converts @self into a human-readable string representation suitable
204 	 * for printing.
205 	 *
206 	 * The result of this function can later be parsed with
207 	 * [func@Gsk.Transform.parse].
208 	 *
209 	 * Params:
210 	 *     string_ = The string to print into
211 	 */
212 	public void print(StringG string_)
213 	{
214 		gsk_transform_print(gskTransform, (string_ is null) ? null : string_.getStringGStruct());
215 	}
216 
217 	alias doref = ref_;
218 	/**
219 	 * Acquires a reference on the given `GskTransform`.
220 	 *
221 	 * Returns: the `GskTransform` with an additional reference
222 	 */
223 	public Transform ref_()
224 	{
225 		auto __p = gsk_transform_ref(gskTransform);
226 
227 		if(__p is null)
228 		{
229 			return null;
230 		}
231 
232 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p);
233 	}
234 
235 	/**
236 	 * Rotates @next @angle degrees in 2D - or in 3D-speak, around the z axis.
237 	 *
238 	 * Params:
239 	 *     angle = the rotation angle, in degrees (clockwise)
240 	 *
241 	 * Returns: The new transform
242 	 */
243 	public Transform rotate(float angle)
244 	{
245 		auto __p = gsk_transform_rotate(gskTransform, angle);
246 
247 		if(__p is null)
248 		{
249 			return null;
250 		}
251 
252 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
253 	}
254 
255 	/**
256 	 * Rotates @next @angle degrees around @axis.
257 	 *
258 	 * For a rotation in 2D space, use [method@Gsk.Transform.rotate]
259 	 *
260 	 * Params:
261 	 *     angle = the rotation angle, in degrees (clockwise)
262 	 *     axis = The rotation axis
263 	 *
264 	 * Returns: The new transform
265 	 */
266 	public Transform rotate3d(float angle, Vec3 axis)
267 	{
268 		auto __p = gsk_transform_rotate_3d(gskTransform, angle, (axis is null) ? null : axis.getVec3Struct());
269 
270 		if(__p is null)
271 		{
272 			return null;
273 		}
274 
275 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
276 	}
277 
278 	/**
279 	 * Scales @next in 2-dimensional space by the given factors.
280 	 *
281 	 * Use [method@Gsk.Transform.scale_3d] to scale in all 3 dimensions.
282 	 *
283 	 * Params:
284 	 *     factorX = scaling factor on the X axis
285 	 *     factorY = scaling factor on the Y axis
286 	 *
287 	 * Returns: The new transform
288 	 */
289 	public Transform scale(float factorX, float factorY)
290 	{
291 		auto __p = gsk_transform_scale(gskTransform, factorX, factorY);
292 
293 		if(__p is null)
294 		{
295 			return null;
296 		}
297 
298 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
299 	}
300 
301 	/**
302 	 * Scales @next by the given factors.
303 	 *
304 	 * Params:
305 	 *     factorX = scaling factor on the X axis
306 	 *     factorY = scaling factor on the Y axis
307 	 *     factorZ = scaling factor on the Z axis
308 	 *
309 	 * Returns: The new transform
310 	 */
311 	public Transform scale3d(float factorX, float factorY, float factorZ)
312 	{
313 		auto __p = gsk_transform_scale_3d(gskTransform, factorX, factorY, factorZ);
314 
315 		if(__p is null)
316 		{
317 			return null;
318 		}
319 
320 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
321 	}
322 
323 	/**
324 	 * Applies a skew transform.
325 	 *
326 	 * Params:
327 	 *     skewX = skew factor, in degrees, on the X axis
328 	 *     skewY = skew factor, in degrees, on the Y axis
329 	 *
330 	 * Returns: The new transform
331 	 *
332 	 * Since: 4.6
333 	 */
334 	public Transform skew(float skewX, float skewY)
335 	{
336 		auto __p = gsk_transform_skew(gskTransform, skewX, skewY);
337 
338 		if(__p is null)
339 		{
340 			return null;
341 		}
342 
343 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
344 	}
345 
346 	/**
347 	 * Converts a `GskTransform` to a 2D transformation matrix.
348 	 *
349 	 * @self must be a 2D transformation. If you are not
350 	 * sure, use gsk_transform_get_category() >=
351 	 * %GSK_TRANSFORM_CATEGORY_2D to check.
352 	 *
353 	 * The returned values have the following layout:
354 	 *
355 	 * ```
356 	 * | xx yx |   |  a  b  0 |
357 	 * | xy yy | = |  c  d  0 |
358 	 * | dx dy |   | tx ty  1 |
359 	 * ```
360 	 *
361 	 * This function can be used to convert between a `GskTransform`
362 	 * and a matrix type from other 2D drawing libraries, in particular
363 	 * Cairo.
364 	 *
365 	 * Params:
366 	 *     outXx = return location for the xx member
367 	 *     outYx = return location for the yx member
368 	 *     outXy = return location for the xy member
369 	 *     outYy = return location for the yy member
370 	 *     outDx = return location for the x0 member
371 	 *     outDy = return location for the y0 member
372 	 */
373 	public void to2d(out float outXx, out float outYx, out float outXy, out float outYy, out float outDx, out float outDy)
374 	{
375 		gsk_transform_to_2d(gskTransform, &outXx, &outYx, &outXy, &outYy, &outDx, &outDy);
376 	}
377 
378 	/**
379 	 * Converts a `GskTransform` to 2D transformation factors.
380 	 *
381 	 * To recreate an equivalent transform from the factors returned
382 	 * by this function, use
383 	 *
384 	 * gsk_transform_skew (
385 	 * gsk_transform_scale (
386 	 * gsk_transform_rotate (
387 	 * gsk_transform_translate (NULL, &GRAPHENE_POINT_T (dx, dy)),
388 	 * angle),
389 	 * scale_x, scale_y),
390 	 * skew_x, skew_y)
391 	 *
392 	 * @self must be a 2D transformation. If you are not sure, use
393 	 *
394 	 * gsk_transform_get_category() >= %GSK_TRANSFORM_CATEGORY_2D
395 	 *
396 	 * to check.
397 	 *
398 	 * Params:
399 	 *     outSkewX = return location for the skew factor
400 	 *         in the  x direction
401 	 *     outSkewY = return location for the skew factor
402 	 *         in the  y direction
403 	 *     outScaleX = return location for the scale
404 	 *         factor in the x direction
405 	 *     outScaleY = return location for the scale
406 	 *         factor in the y direction
407 	 *     outAngle = return location for the rotation angle
408 	 *     outDx = return location for the translation
409 	 *         in the x direction
410 	 *     outDy = return location for the translation
411 	 *         in the y direction
412 	 *
413 	 * Since: 4.6
414 	 */
415 	public void to2dComponents(out float outSkewX, out float outSkewY, out float outScaleX, out float outScaleY, out float outAngle, out float outDx, out float outDy)
416 	{
417 		gsk_transform_to_2d_components(gskTransform, &outSkewX, &outSkewY, &outScaleX, &outScaleY, &outAngle, &outDx, &outDy);
418 	}
419 
420 	/**
421 	 * Converts a `GskTransform` to 2D affine transformation factors.
422 	 *
423 	 * To recreate an equivalent transform from the factors returned
424 	 * by this function, use
425 	 *
426 	 * gsk_transform_scale (gsk_transform_translate (NULL,
427 	 * &GRAPHENE_POINT_T (dx, dy)),
428 	 * sx, sy)
429 	 *
430 	 * @self must be a 2D affine transformation. If you are not
431 	 * sure, use
432 	 *
433 	 * gsk_transform_get_category() >= %GSK_TRANSFORM_CATEGORY_2D_AFFINE
434 	 *
435 	 * to check.
436 	 *
437 	 * Params:
438 	 *     outScaleX = return location for the scale
439 	 *         factor in the x direction
440 	 *     outScaleY = return location for the scale
441 	 *         factor in the y direction
442 	 *     outDx = return location for the translation
443 	 *         in the x direction
444 	 *     outDy = return location for the translation
445 	 *         in the y direction
446 	 */
447 	public void toAffine(out float outScaleX, out float outScaleY, out float outDx, out float outDy)
448 	{
449 		gsk_transform_to_affine(gskTransform, &outScaleX, &outScaleY, &outDx, &outDy);
450 	}
451 
452 	/**
453 	 * Computes the actual value of @self and stores it in @out_matrix.
454 	 *
455 	 * The previous value of @out_matrix will be ignored.
456 	 *
457 	 * Params:
458 	 *     outMatrix = The matrix to set
459 	 */
460 	public void toMatrix(out Matrix outMatrix)
461 	{
462 		graphene_matrix_t* outoutMatrix = sliceNew!graphene_matrix_t();
463 
464 		gsk_transform_to_matrix(gskTransform, outoutMatrix);
465 
466 		outMatrix = ObjectG.getDObject!(Matrix)(outoutMatrix, true);
467 	}
468 
469 	/**
470 	 * Converts a matrix into a string that is suitable for printing.
471 	 *
472 	 * The resulting string can be parsed with [func@Gsk.Transform.parse].
473 	 *
474 	 * This is a wrapper around [method@Gsk.Transform.print].
475 	 *
476 	 * Returns: A new string for @self
477 	 */
478 	public override string toString()
479 	{
480 		auto retStr = gsk_transform_to_string(gskTransform);
481 
482 		scope(exit) Str.freeString(retStr);
483 		return Str.toString(retStr);
484 	}
485 
486 	/**
487 	 * Converts a `GskTransform` to a translation operation.
488 	 *
489 	 * @self must be a 2D transformation. If you are not
490 	 * sure, use
491 	 *
492 	 * gsk_transform_get_category() >= %GSK_TRANSFORM_CATEGORY_2D_TRANSLATE
493 	 *
494 	 * to check.
495 	 *
496 	 * Params:
497 	 *     outDx = return location for the translation
498 	 *         in the x direction
499 	 *     outDy = return location for the translation
500 	 *         in the y direction
501 	 */
502 	public void toTranslate(out float outDx, out float outDy)
503 	{
504 		gsk_transform_to_translate(gskTransform, &outDx, &outDy);
505 	}
506 
507 	/**
508 	 * Applies all the operations from @other to @next.
509 	 *
510 	 * Params:
511 	 *     other = Transform to apply
512 	 *
513 	 * Returns: The new transform
514 	 */
515 	public Transform transform(Transform other)
516 	{
517 		auto __p = gsk_transform_transform(gskTransform, (other is null) ? null : other.getTransformStruct());
518 
519 		if(__p is null)
520 		{
521 			return null;
522 		}
523 
524 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
525 	}
526 
527 	/**
528 	 * Transforms a `graphene_rect_t` using the given transform @self.
529 	 *
530 	 * The result is the bounding box containing the coplanar quad.
531 	 *
532 	 * Params:
533 	 *     rect = a `graphene_rect_t`
534 	 *     outRect = return location for the bounds
535 	 *         of the transformed rectangle
536 	 */
537 	public void transformBounds(Rect rect, out Rect outRect)
538 	{
539 		graphene_rect_t* outoutRect = sliceNew!graphene_rect_t();
540 
541 		gsk_transform_transform_bounds(gskTransform, (rect is null) ? null : rect.getRectStruct(), outoutRect);
542 
543 		outRect = ObjectG.getDObject!(Rect)(outoutRect, true);
544 	}
545 
546 	/**
547 	 * Transforms a `graphene_point_t` using the given transform @self.
548 	 *
549 	 * Params:
550 	 *     point = a `graphene_point_t`
551 	 *     outPoint = return location for
552 	 *         the transformed point
553 	 */
554 	public void transformPoint(Point point, out Point outPoint)
555 	{
556 		graphene_point_t* outoutPoint = sliceNew!graphene_point_t();
557 
558 		gsk_transform_transform_point(gskTransform, (point is null) ? null : point.getPointStruct(), outoutPoint);
559 
560 		outPoint = ObjectG.getDObject!(Point)(outoutPoint, true);
561 	}
562 
563 	/**
564 	 * Translates @next in 2-dimensional space by @point.
565 	 *
566 	 * Params:
567 	 *     point = the point to translate the transform by
568 	 *
569 	 * Returns: The new transform
570 	 */
571 	public Transform translate(Point point)
572 	{
573 		auto __p = gsk_transform_translate(gskTransform, (point is null) ? null : point.getPointStruct());
574 
575 		if(__p is null)
576 		{
577 			return null;
578 		}
579 
580 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
581 	}
582 
583 	/**
584 	 * Translates @next by @point.
585 	 *
586 	 * Params:
587 	 *     point = the point to translate the transform by
588 	 *
589 	 * Returns: The new transform
590 	 */
591 	public Transform translate3d(Point3D point)
592 	{
593 		auto __p = gsk_transform_translate_3d(gskTransform, (point is null) ? null : point.getPoint3DStruct());
594 
595 		if(__p is null)
596 		{
597 			return null;
598 		}
599 
600 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
601 	}
602 
603 	/**
604 	 * Releases a reference on the given `GskTransform`.
605 	 *
606 	 * If the reference was the last, the resources associated to the @self are
607 	 * freed.
608 	 */
609 	public void unref()
610 	{
611 		gsk_transform_unref(gskTransform);
612 	}
613 
614 	/**
615 	 * Parses the given @string into a transform and puts it in
616 	 * @out_transform.
617 	 *
618 	 * Strings printed via [method@Gsk.Transform.to_string]
619 	 * can be read in again successfully using this function.
620 	 *
621 	 * If @string does not describe a valid transform, %FALSE is
622 	 * returned and %NULL is put in @out_transform.
623 	 *
624 	 * Params:
625 	 *     string_ = the string to parse
626 	 *     outTransform = The location to put the transform in
627 	 *
628 	 * Returns: %TRUE if @string described a valid transform.
629 	 */
630 	public static bool parse(string string_, out Transform outTransform)
631 	{
632 		GskTransform* outoutTransform = null;
633 
634 		auto __p = gsk_transform_parse(Str.toStringz(string_), &outoutTransform) != 0;
635 
636 		outTransform = ObjectG.getDObject!(Transform)(outoutTransform);
637 
638 		return __p;
639 	}
640 }